﻿Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports System.Text

Public Class BackBlaze
    Public ApplicationKey As String
    Public AccountID As String
    Public AuthToken As String = Nothing
    Dim DownloadURL As String = Nothing
    Dim ApiURL As String = Nothing

    ''' <summary>
    ''' Create a new BackBlaze Class Instance
    ''' </summary>
    ''' <param name="accID">Your B2 Account ID</param>
    ''' <param name="appKey">Your B2 Application Key</param>
    Sub New(ByVal accID As String, ByVal appKey As String)
        ApplicationKey = appKey
        AccountID = accID
    End Sub

    ''' <summary>
    ''' Send a B2BackBlaze Authorization Request
    ''' </summary>
    Public Sub B2AuthorizeAccount()
        'B2 Cloud Storage Account ID
        Dim acc As String = Me.AccountID

        'B2 Cloud Storage Application Key
        Dim app As String = Me.ApplicationKey

        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        Dim credentials As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(acc + ":" + app))
        client.Headers.Item(HttpRequestHeader.Authorization) = "Basic " & credentials
        Dim Content As String = client.DownloadString("https://api.backblaze.com/b2api/v1/b2_authorize_account")

        Dim Result As B2AuthorizeResult = JsonConvert.DeserializeObject(Of B2AuthorizeResult)(Content)
        AuthToken = Result.authorizationToken
        ApiURL = Result.apiUrl
        DownloadURL = Result.downloadUrl
    End Sub

    ''' <summary>
    ''' Get the info of a file, given the id of it.
    ''' </summary>
    ''' <param name="FileID"></param>
    ''' <returns></returns>
    Public Function B2GetFileInfo(ByVal FileID As String) As B2FileInfoResult
        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = Me.AuthToken
        client.Headers.Item(HttpRequestHeader.ContentType) = "application/json; charset=utf-8"

        Dim body As String = "{""fileId"": ""FID""}".Replace("FID", FileID)

        Dim Content As String = client.UploadString(ApiURL & "/b2api/v1/b2_get_file_info", body)

        Dim Result As B2FileInfoResult = JsonConvert.DeserializeObject(Of B2FileInfoResult)(Content)

        Return Result
    End Function

    ''' <summary>
    ''' List files in B2 Backblaze API
    ''' </summary>
    ''' <param name="BucketID">The Bucket ID</param>
    ''' <param name="startFileName">The filename to start. Use "" if null.</param>
    ''' <returns></returns>
    Public Function B2ListFiles(ByVal BucketID As String, ByVal startFileName As String) As List(Of B2BackBlaze.File)
        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = Me.AuthToken
        client.Headers.Item(HttpRequestHeader.ContentType) = "application/json; charset=utf-8"

        Dim body As String = "{""bucketId"": ""BUCKID"", ""startFileName"": ""SNAME""}".Replace("BUCKID", BucketID).Replace("SNAME", startFileName)

        Dim Content As String = client.UploadString(ApiURL & "/b2api/v1/b2_list_file_names", body)

        Dim Result As B2ListResult = JsonConvert.DeserializeObject(Of B2ListResult)(Content)

        Return Result.files
    End Function

    ''' <summary>
    ''' Download a file from the B2 Cloud
    ''' </summary>
    ''' <returns></returns>
    Public Function B2DownloadFile(ByVal filename As String) As Byte()
        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = Me.AuthToken

        Dim Content As Byte() = client.DownloadData(Me.DownloadURL & "/file/PutVault/" & filename)

        Return Content
    End Function

    ''' <summary>
    ''' Get the Upload URL from the Backblaze B2 API
    ''' </summary>
    ''' <param name="BucketID">The bucket id</param>
    ''' <returns></returns>
    Public Function B2GetUploadUrl(ByVal BucketID As String) As B2UploadResult
        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = Me.AuthToken
        client.Headers.Item(HttpRequestHeader.ContentType) = "application/json; charset=utf-8"

        Dim body As String = "{""bucketId"": ""BUCKID""}".Replace("BUCKID", BucketID)

        Dim Content As String = client.UploadString(ApiURL & "/b2api/v1/b2_get_upload_url", body)

        Dim Result As B2UploadResult = JsonConvert.DeserializeObject(Of B2UploadResult)(Content)

        Return Result
    End Function

    ''' <summary>
    ''' Delete a file from the Backblaze B2 API
    ''' </summary>
    ''' <param name="filename">the filename to delete</param>
    ''' <param name="fileid">the id of the file to delete</param>
    ''' <returns></returns>
    Public Function B2DeleteFile(ByVal filename As String, ByVal fileid As String) As B2DeleteResult
        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = Me.AuthToken
        client.Headers.Item(HttpRequestHeader.ContentType) = "application/json; charset=utf-8"

        Dim body As String = "{""fileName"": ""FNAME"", ""fileId"": ""FID""}".Replace("FNAME", filename).Replace("FID", fileid)

        Dim Content As String = client.UploadString(ApiURL & "/b2api/v1/b2_delete_file_version", body)

        Dim Result As B2DeleteResult = JsonConvert.DeserializeObject(Of B2DeleteResult)(Content)

        Return Result
    End Function

    ''' <summary>
    ''' Upload a file to the B2 API Cloud
    ''' </summary>
    ''' <param name="filename"></param>
    ''' <param name="contenttype"></param>
    ''' <returns></returns>
    Public Function B2UploadFile(ByVal filename As String, ByVal data As Byte(), ByVal url As String,
                                  ByVal sha As String, ByVal ulAuthToken As String, Optional ByVal contenttype As String = "b2/x-auto") As B2UploadFileResult

        Dim client As New CustomWebClient()
        client.UseDefaultCredentials = True

        client.Headers.Item(HttpRequestHeader.Authorization) = ulAuthToken

        client.Headers.Item(HttpRequestHeader.ContentType) = contenttype
        client.Headers.Item("X-Bz-File-Name") = filename
        client.Headers.Item("X-Bz-Content-Sha1") = sha
        client.Headers.Item(HttpRequestHeader.ContentType) = contenttype

        Dim resp As Byte() = client.UploadData(url, data)

        Dim Content As String = System.Text.Encoding.Default.GetString(resp)

        Dim Result As B2UploadFileResult = JsonConvert.DeserializeObject(Of B2UploadFileResult)(Content)

        Return Result
    End Function
End Class

Public Class CustomWebClient
    Inherits WebClient
    Protected Overrides Function GetWebRequest(address As Uri) As WebRequest
        Dim request = MyBase.GetWebRequest(address)
        If TypeOf request Is HttpWebRequest Then
            DirectCast(request, HttpWebRequest).KeepAlive = False
            DirectCast(request, HttpWebRequest).ProtocolVersion = HttpVersion.Version10
        End If

        Return request
    End Function
End Class
